package com.lzhpo.core.service;

import com.google.common.collect.Lists;
import com.lzhpo.core.domain.PrizeInfoEntity;
import com.lzhpo.core.domain.concord.CodeThreeDataVo;
import com.lzhpo.core.domain.concord.PassDataVo;
import com.lzhpo.core.domain.concord.SpanDataVo;
import com.lzhpo.core.utils.*;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author <a href="lijing1@wxchina.com@wxchina.com">Lijin</a>
 * @Description TODO
 * @Date 2019/12/20 13:10
 * @Version 1.0
 **/
@Service
public class CodeThreeDataService {

    @Autowired
    private PrizeDataService prizeDataService;


    @Autowired
    private DragonDataService dragonDataService;

    @Autowired
    private CommonService commonService;


    private void comparaVoWithPreVo(SpanDataVo vo, SpanDataVo preVo) {
        dragonDataService.compareTwoArr(vo.getSpanValueArr(), preVo.getSpanValueArr());
        dragonDataService.compareTwoArr(vo.getMixValuesArr(), preVo.getMixValuesArr());
    }


    private List<List<String>> tranSpanDataToListArr(List<SpanDataVo> listResult) {
        List<List<String>> bigList = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(listResult)) {
            listResult.forEach(s -> {
                List<String> span = Lists.newArrayList(s.getSpanValueArr());
                List<String> mix = Lists.newArrayList(s.getMixValuesArr());
                List<String> listArr = Lists.newArrayList();
                listArr.addAll(span);
                listArr.addAll(mix);
                bigList.add(listArr);
            });
        }
        return bigList;
    }

    public List<SpanDataVo> getSpanIndexList() {

        List<PrizeInfoEntity> remoteList =
                prizeDataService.queryFiveHundredPrizeDataFromDb(DataTypeEnum.BEIJING_BOAT.getType());
        List<SpanDataVo> result = Lists.newArrayList();
        for (int i = 0; i < remoteList.size(); i++) {
            PrizeInfoEntity entity = remoteList.get(i);
            SpanDataVo vo = new SpanDataVo();
            commonService.copyCommonVo(entity, vo);
            int sum = CalculateUtil.getSpanValue(entity);
            String[] spanArr = MyStrUtil.getInitSumValueArr(8);
            spanArr[sum - 2] = "ok," + sum;
            vo.setSpanValueArr(spanArr);
            if (result.size() == 0) {
                //第一行默认都是断
                String[] arrTemp2 = {"no,1", "ok,断", "no,1", "ok,断", "no,1"};
                vo.setMixValuesArr(arrTemp2);
            } else {
                SpanDataVo preVo = result.get(result.size() - 1);
                int preSum = CalculateUtil.getSpanValue(preVo);
                vo.setMixValuesArr(dragonDataService.getPassBreakFallArr(sum, preSum));
                comparaVoWithPreVo(vo, preVo);
            }
            result.add(vo);

        }
        return result;
    }


    public List<CodeThreeDataVo> getCodeThreeFourCommonList(
            Map<Integer, List<Integer>> codeThreeMapDesc,
            int dataType, boolean isFive

    ) {
        List<PrizeInfoEntity> remoteList =
                prizeDataService.
                        queryFiveHundredPrizeDataWithSize(dataType,300);
        List<CodeThreeDataVo> result =
                Lists.newArrayList();
        for (int i = 0, size = remoteList.size(); i < size; i++) {
            PrizeInfoEntity entity = remoteList.get(i);
            CodeThreeDataVo vo = new CodeThreeDataVo();
            commonService.copyCommonVo(entity, vo);
            vo.setPrizeNo04(entity.getPrizeNo04());
            vo.setPrizeNo05(entity.getPrizeNo05());
            /*if (dataType == 3) {
                delPrizeNumStartZero(vo);
            }*/
            String[] danmaArr = MyStrUtil.getInitSumValueArr(10);
            String[] firstArr = MyStrUtil.getInitSumValueArr(10);
            String[] secondrr = MyStrUtil.getInitSumValueArr(10);
            String[] thirdArr = MyStrUtil.getInitSumValueArr(10);
            String[] statusArr = MyStrUtil.getInitSumValueArr(6);

            //CalculateUtil
            List<Integer> firstValueMapList =
                    codeThreeMapDesc.get(Integer.valueOf(vo.getPrizeNo01()));
            List<Integer> secondValueMapList =
                    codeThreeMapDesc.get(Integer.valueOf(vo.getPrizeNo02()));
            List<Integer> thirdValueMapList =
                    codeThreeMapDesc.get(Integer.valueOf(vo.getPrizeNo03()));
            for (int j = 0; j < firstArr.length; j++) {
                int temp = isFive ? j : j + 1;
                if (firstValueMapList.contains(temp)) {
                    firstArr[j] = "ok," + temp;
                }
            }
            for (int j = 0; j < secondrr.length; j++) {
                int temp = isFive ? j : j + 1;
                if (secondValueMapList.contains(temp)) {
                    secondrr[j] = "ok," + temp;
                }
            }
            for (int j = 0; j < thirdArr.length; j++) {
                int temp = isFive ? j : j + 1;
                if (thirdValueMapList.contains(temp)) {
                    thirdArr[j] = "ok," + temp;
                }
            }

            //胆码--start
            int num1 = Integer.valueOf(entity.getPrizeNo01());
            int num2 = Integer.valueOf(entity.getPrizeNo02());
            int num3 = Integer.valueOf(entity.getPrizeNo03());
          //  String[] regionArr = MyStrUtil.getInitSumValueArr(10);
            for (int j = 0; j < danmaArr.length; j++) {
                if (j==num1 || j==num2 || j==num3){
                    danmaArr[j]="ok,"+j;
                }
            }
            //胆码 --end
            //形态统计---start
            //形态统计---end

            vo.setFirstValueArr(firstArr);
            vo.setSecondValueArr(secondrr);
            vo.setThirdValueArr(thirdArr);
            vo.setDammaValueArr(danmaArr);
            vo.setStatusStatArr(statusArr);

            if (result.size() > 0) {
                CodeThreeDataVo preVo = result.get(result.size() - 1);
                //当前行需要和上一行比较
                comparaVoWithPreVoCodeThree(vo, preVo);
            }
            result.add(vo);
        }

        return result;
    }


    public List<CodeThreeDataVo> getCodeThreeIndexList(ConditionEnum type) {
        Map<Integer, List<Integer>> codeThreeMapDesc =
                CalculateUtil.codeThreeMapDesc;
        if (type == ConditionEnum.CODEFOUR) {
            codeThreeMapDesc = CalculateUtil.codeFourMapDesc;
        }
        return getCodeThreeFourCommonList(codeThreeMapDesc,
                DataTypeEnum.BEIJING_BOAT.getType(), false
        );
    }

    public List<CodeThreeDataVo> getCodeThreeFiveIndexList(ConditionEnum type,
                                                       Integer dataType) {
        Map<Integer, List<Integer>> codeThreeMapDesc =
                CalculateUtil.codeThreeFiveMapDesc;
        return getCodeThreeFourCommonList(codeThreeMapDesc,
                DataTypeEnum.ARRANGE_FIVE.getType(), true
        );
    }

    private void comparaVoWithPreVoPass(PassDataVo vo, PassDataVo preVo) {
        dragonDataService.compareTwoArr(vo.getNumRegions(),
                preVo.getNumRegions());
        dragonDataService.compareTwoArr(vo.getContinuNumbers(),
                preVo.getContinuNumbers());
        dragonDataService.compareTwoArr(vo.getPassNumbers(),
                preVo.getPassNumbers());
        dragonDataService.compareTwoArr(vo.getPartiNumbers(),
                preVo.getPartiNumbers());
        dragonDataService.compareTwoArr(vo.getFallNumbers(),
                preVo.getFallNumbers());

    }

    private void comparaVoWithPreVoCodeThree(CodeThreeDataVo vo, CodeThreeDataVo preVo) {
        dragonDataService.compareTwoArr(vo.getDammaValueArr(),
                preVo.getDammaValueArr());
        dragonDataService.compareTwoArr(vo.getFirstValueArr(),
                preVo.getFirstValueArr());
        dragonDataService.compareTwoArr(vo.getSecondValueArr(),
                preVo.getSecondValueArr());
        dragonDataService.compareTwoArr(vo.getThirdValueArr(),
                preVo.getThirdValueArr());
        dragonDataService.calcStatusStatArr(vo,preVo);
        dragonDataService.compareTwoArr(vo.getStatusStatArr(),
                preVo.getStatusStatArr());
    }

    public List<String[]> getBottomStaticsCodeThree(List<CodeThreeDataVo> listResult) {
        if (CollectionUtils.isEmpty(listResult)){
            return  Lists.newArrayList();
        }
        List<List<String>> bigList = Lists.newArrayList();
        listResult.forEach(s -> {
            List<String> listTemp = Lists.newArrayList();
            listTemp.addAll(Stream.of(s.getDammaValueArr()).collect(Collectors.toList()));
            listTemp.addAll(Stream.of(s.getFirstValueArr()).collect(Collectors.toList()));
            listTemp.addAll(Stream.of(s.getSecondValueArr()).collect(Collectors.toList()));
            listTemp.addAll(Stream.of(s.getThirdValueArr()).collect(Collectors.toList()));
            listTemp.addAll(Lists.newArrayList(s.getStatusStatArr()));
            bigList.add(listTemp);
        });
        return commonService.getCommonBottomStatics(bigList, 46);
    }

    public List<String[]> getBottomStaticsPass(List<PassDataVo> listResult) {
        List<List<String>> bigList = Lists.newArrayList();
        listResult.forEach(s -> {
            List<String> listTemp = Lists.newArrayList();
            listTemp.addAll(Stream.of(s.getNumRegions()).collect(Collectors.toList()));
            listTemp.addAll(Stream.of(s.getContinuNumbers()).collect(Collectors.toList()));
            listTemp.addAll(Stream.of(s.getPassNumbers()).collect(Collectors.toList()));
            listTemp.addAll(Stream.of(s.getPartiNumbers()).collect(Collectors.toList()));
            listTemp.addAll(Stream.of(s.getFallNumbers()).collect(Collectors.toList()));
            bigList.add(listTemp);
        });
        return commonService.getCommonBottomStatics(bigList, 25);
    }

    public List<PassDataVo> getPassIndexList(int termSize) {
        List<PrizeInfoEntity> remoteList =
                prizeDataService.queryFiveHundredPrizeDataWithSize(
                        DataTypeEnum.ARRANGE_FIVE.getType(),termSize);
        List<PassDataVo> result =
                Lists.newArrayList();
        for (int i = 0, size = remoteList.size(); i < size; i++) {
            PrizeInfoEntity entity = remoteList.get(i);
            PassDataVo vo = new PassDataVo();
            commonService.copyCommonVo(entity, vo);
            vo.setPrizeNo01(Integer.valueOf(vo.getPrizeNo01()).toString());
            vo.setPrizeNo02(Integer.valueOf(vo.getPrizeNo02()).toString());
            vo.setPrizeNo03(Integer.valueOf(vo.getPrizeNo03()).toString());

            String[] numRegions = MyStrUtil.getInitSumValueArr(10);
            String[] continuNumbers = MyStrUtil.getInitSumValueArr(3);
            String[] passNumbers = MyStrUtil.getInitSumValueArr(4);
            String[] partiNumbers = MyStrUtil.getInitSumValueArr(4);
            String[] fallNumbers = MyStrUtil.getInitSumValueArr(4);
            int first = Integer.valueOf(vo.getPrizeNo01());
            int second = Integer.valueOf(vo.getPrizeNo02());
            int third = Integer.valueOf(vo.getPrizeNo03());
            numRegions[first] = "ok," + first;
            numRegions[second] = "ok," + second;
            numRegions[third] = "ok," + third;
            vo.setNumRegions(numRegions);
            int temp = 0;
            List<Integer> unsorteds = Lists.newArrayList(first, second, third);
            List<Integer> sorteds = unsorteds.stream().sorted(Comparator.naturalOrder()).collect(Collectors.toList());
            if ((sorteds.get(0) + 1) == sorteds.get(1)) {
                temp++;
            }
            if ((sorteds.get(1) + 1) == sorteds.get(2)) {
                temp++;
            }
            continuNumbers[temp] = "ok," + temp;
            vo.setContinuNumbers(continuNumbers);
            //计算传码
            if (i == 0) {
                passNumbers[0] = "ok,0";
                partiNumbers[0] = "ok,0";
                fallNumbers[0] = "ok,0";
            }
            if (i == 1) {
                temp = getPassValue(vo, result);
                passNumbers[temp] = "ok," + temp;//传码
                partiNumbers[0] = "ok,0";//隔码
                temp = getFallValue(vo, result, 1);
                fallNumbers[temp] = "ok," + temp;//落码
            }
            if (i >= 2) {
                temp = getPassValue(vo, result);
                passNumbers[temp] = "ok," + temp;//传码
                temp = getFallValue(vo, result, 2);
                partiNumbers[temp] = "ok," + temp;//隔码
                temp = getFallValue(vo, result, 1);
                fallNumbers[temp] = "ok," + temp;//落码

            }
            vo.setPassNumbers(passNumbers);
            vo.setPartiNumbers(partiNumbers);
            vo.setFallNumbers(fallNumbers);
            if (result.size() > 0) {
                PassDataVo preVo = result.get(result.size() - 1);
                comparaVoWithPreVoPass(vo, preVo);
            }
            result.add(vo);
        }
        return result;
    }

    private int getFallValue(PassDataVo vo, List<PassDataVo> result, int index) {
        int fallN = 0;
        PassDataVo pre = result.get(result.size() - index);
        List<Integer> preTermNums = Lists.newArrayList(
                Integer.valueOf(pre.getPrizeNo01()),
                Integer.valueOf(pre.getPrizeNo02()),
                Integer.valueOf(pre.getPrizeNo03())
        );
        List<Integer> curTermNums = Lists.newArrayList(
                Integer.valueOf(vo.getPrizeNo01()),
                Integer.valueOf(vo.getPrizeNo02()),
                Integer.valueOf(vo.getPrizeNo03())
        );
        for (Integer n : preTermNums) {
            if (curTermNums.contains(n)) {
                fallN++;
            }
        }
        return fallN;
    }

    private int getPassValue(PassDataVo vo, List<PassDataVo> result) {
        int temp = 0;
        PassDataVo pre = result.get(result.size() - 1);
        List<Integer> preTermNums = Lists.newArrayList(
                Integer.valueOf(pre.getPrizeNo01()),
                Integer.valueOf(pre.getPrizeNo02()),
                Integer.valueOf(pre.getPrizeNo03())
        );
        List<Integer> curTermNums = Lists.newArrayList(
                Integer.valueOf(vo.getPrizeNo01()),
                Integer.valueOf(vo.getPrizeNo02()),
                Integer.valueOf(vo.getPrizeNo03())
        );
        //计算传码
        for (Integer curN : curTermNums) {

            for (Integer preN : preTermNums) {
                if (curN + 1 == preN) {
                    temp++;
                    break;
                }
                if (curN - 1 == preN) {
                    temp++;
                    break;
                }
                if (curN == 9 && preN == 0) {
                    temp++;
                    break;
                }
                if (curN == 0 && preN == 9) {
                    temp++;
                    break;

                }
            }
        }
        return temp;
    }

    public List<CodeThreeDataVo> getCodeThreeIndexFiveList(DataTypeEnum dataTypeEnum) {
        Map<Integer, List<Integer>> codeThreeMapDesc =
                CalculateFiveUtil.codeFourMapDesc;
        return getCodeThreeFourCommonList(codeThreeMapDesc,
                dataTypeEnum.getType(), true);


    }

    public void delPrizeNumStartZero(CodeThreeDataVo vo) {
        vo.setPrizeNo01(Integer.valueOf(vo.getPrizeNo01()).toString());
        vo.setPrizeNo02(Integer.valueOf(vo.getPrizeNo02()).toString());
        vo.setPrizeNo03(Integer.valueOf(vo.getPrizeNo03()).toString());
        vo.setPrizeNo04(Integer.valueOf(vo.getPrizeNo04()).toString());
        vo.setPrizeNo05(Integer.valueOf(vo.getPrizeNo05()).toString());

    }

    public List<CodeThreeDataVo> getCodeFiveIndexList(Integer dataType) {

        Map<Integer, List<Integer>> mapdesc= null;
        boolean isFive=true;
        if (dataType==2){
            mapdesc=CalculateUtil.boatCodeFiveFiveMapDesc;
            isFive=false;
        }
        if (dataType==3){
            mapdesc=CalculateUtil.rangeCodeFiveFiveMapDesc;
            isFive=true;
        }

        List<PrizeInfoEntity> remoteList =
                prizeDataService.
                        queryFiveHundredPrizeDataFromDb(dataType);
        if (dataType==3){
            remoteList = prizeDataService.queryFiveHundredPrizeDataWithSize(dataType,145);
        }
        List<CodeThreeDataVo> result =
                Lists.newArrayList();
        for (int i = 0, size = remoteList.size(); i < size; i++) {
            PrizeInfoEntity entity = remoteList.get(i);
            CodeThreeDataVo vo = new CodeThreeDataVo();
            commonService.copyCommonVo(entity, vo);
            vo.setPrizeNo04(entity.getPrizeNo04());
            vo.setPrizeNo05(entity.getPrizeNo05());
            if (dataType == 3) {
                delPrizeNumStartZero(vo);
            }
            String[] firstArr = MyStrUtil.getInitSumValueArr(10);
            String[] secondrr = MyStrUtil.getInitSumValueArr(10);
            String[] thirdArr = MyStrUtil.getInitSumValueArr(10);

            List<Integer> firstValueMapList =
                    mapdesc.get(Integer.valueOf(vo.getPrizeNo01()));
            List<Integer> secondValueMapList =
                    mapdesc.get(Integer.valueOf(vo.getPrizeNo02()));
            List<Integer> thirdValueMapList =
                    mapdesc.get(Integer.valueOf(vo.getPrizeNo03()));


            for (int j = 0; j < firstArr.length; j++) {
                int temp = isFive ? j : j + 1;
                if (firstValueMapList.contains(temp)) {
                    firstArr[j] = "ok," + temp;
                }
            }
            for (int j = 0; j < secondrr.length; j++) {
                int temp = isFive ? j : j + 1;
                if (secondValueMapList.contains(temp)) {
                    secondrr[j] = "ok," + temp;
                }
            }
            for (int j = 0; j < thirdArr.length; j++) {
                int temp = isFive ? j : j + 1;
                if (thirdValueMapList.contains(temp)) {
                    thirdArr[j] = "ok," + temp;
                }
            }
            vo.setFirstValueArr(firstArr);
            vo.setSecondValueArr(secondrr);
            vo.setThirdValueArr(thirdArr);
            if (result.size() > 0) {
                CodeThreeDataVo preVo = result.get(result.size() - 1);
                comparaVoWithPreVoCodeThree(vo, preVo);
            }
            result.add(vo);

        }

        return result;
    }
}